package com.example.wac.event.listener;

import com.alibaba.fastjson.JSONObject;
import com.example.wac.constant.Constant;
import com.example.wac.event.MessageEvent;
import com.example.wac.mail.ToEmail;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * @author wuancheng
 * @description 事件监听者
 * @date 2021-09-08 16:48:00
 */

@Component
@Slf4j
public class MessageListeners {

    @Autowired
    private DefaultMQProducer producer;

    @Value("${rocketMq.TOPIC}")
    private String topic;

    @Async(value = "threadPoolTaskExecutor")
    @EventListener(value = {MessageEvent.class})
    public void onApplicationEvent(ApplicationEvent event) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
        if (event instanceof MessageEvent){
            MessageEvent messageEvent = (MessageEvent) event;
            MDC.put(Constant.TRANSACTION_ID, messageEvent.getTransactionId());
            ToEmail email = (ToEmail) messageEvent.getSource();
            //序列化对象发送消息
            Message message = new Message(topic, "mailTag",JSONObject.toJSONString(email).getBytes());
            // 设置延时消息
//            message.setDelayTimeLevel(1);
            log.info("发送mq消息调用邮件发送服务");
            // 同步发送 同步发送是指发送方发出数据后等待接收方发回响应后在发送下一个数据包
            producer.send(message);
            // 单向发送 单向发送是指只负责发送消息而不等待接收方发回响应且没有回调函数
//            producer.sendOneway(message);
            // 异步发送 异步发送是指发送方发出数据后不等接收方发回响应就发出下一个数据包
            SendCallback sendCallback = new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    System.out.println("异步发送接受成功");
                }

                @Override
                public void onException(Throwable throwable) {
                    log.info("异步发送接受失败", throwable);
                }
            };
//            producer.send(message, sendCallback);
        }
    }

}
